import itemOpen from './components/open.vue';
import itemUpload from './components/upload.vue';
import { Loading } from 'element-ui';
import generateOSS from '@/utils/upload_handler_miva';
import CryptoJS from 'crypto-js';
import {
  getHistoryEditArchive,
  createArchive,
  setArchive,
  getArchive,
  createAudioResource,
  sortAudioResource,
  editAudioResource,
  deleteAudioResource
} from '@/api/audio.js';

export default {
  components: { itemUpload, itemOpen },
  data() {
    return {
      isSubmit: false,
      isEdit: false,
      isHistoryToOpen: null,
      loading: true,
      isUploading: false,
      uploading: [], // 记录所有正在上传的任务
      resourcesList: [],
      formData: {
        classify_id: '',
        cover: '',
        title: '',
        desc: ''
      }
    };
  },
  beforeRouteLeave(to, form, next) {
    const { isSubmit, isEdit } = this;
    if (
      isSubmit ||
      isEdit === false ||
      window.confirm('离开可能会有数据不会被保存, 确认离开嘛?')
    ) {
      window.onbeforeunload = null;
      return next();
    }
    next(false);
  },
  async mounted() {
    await this.checkHistoryArchive();
    this.loading = false;
  },
  methods: {
    async checkHistoryArchive() {
      const { code, data } = await getHistoryEditArchive();
      if (code === 404) {
        this.isHistoryToOpen = false;
        return false;
      }
      this.formatArchiveData(data);
      this.isHistoryToOpen = true;
      return true;
    },
    async createArchive() {
      const { message, data } = await createArchive();
      this.formatArchiveData(data);
      this.$message({ type: 'success', message });
      window.onbeforeunload = () => '关闭提示';
    },
    formatArchiveData(data) {
      this.formData = data;
      this.resourcesList = data.resources;
      for (const resource of this.resourcesList) {
        resource.progress = 100;
      }
    },
    async openClickHandler() {
      if (!this.isHistoryToOpen) {
        await this.createArchive();
      }
      this.isEdit = true;
    },
    async checkFileHandler(file) {
      if (!this.verifyFileMime(file)) {
        return;
      }
      const fileData = this.formatFileData(file);
      const fileInfo = await this.analysisAudio(file);
      const audioData = { ...fileData, ...fileInfo };
      await this.uploadHandler(file, audioData);
    },
    verifyFileMime(file) {
      const acceptMimeTyep = [
        'audio/mpeg',
        'audio/mp3',
        'audio/ogg',
        'audio/wav'
      ];
      if (acceptMimeTyep.indexOf(file.type) === -1) {
        this.$message.error('所选文件格式不支持');
        return false;
      }
      return true;
    },
    formatFileData(file) {
      const data = {
        name: file.name.slice(0, file.name.lastIndexOf('.')),
        suffix: file.name.slice(file.name.lastIndexOf('.') + 1),
        size: file.size,
        mime: file.type,
        sign: `${Date.now()}-${CryptoJS.SHA256(`${Date.now()}`).toString()}`,
        progress: 0,
        isComplete: true,
        isUploading: true
      };
      return data;
    },
    analysisAudio(file) {
      const returnBody = {
        duration: 0
      };
      const filePath = URL.createObjectURL(file);
      const audio = new Audio(filePath);
      return new Promise(resolve => {
        audio.onloadedmetadata = () => {
          returnBody.duration = Math.ceil(audio.duration);
          resolve(returnBody);
        };
      });
    },
    async uploadHandler(file, fileData) {
      const dir = 'audio/' + fileData.suffix;
      const name = `-${fileData.sign}.${fileData.suffix}`;
      const client = await generateOSS();
      const uploadData = { ...fileData };
      uploadData.sort = this.resourcesList.length;
      uploadData.ossClinet = client;
      this.resourcesList.push(uploadData);
      try {
        const res_upload = await client.multipartUpload(dir + name, file, {
          progress: val => {
            uploadData.progress = Number(parseInt(val * 10000)) / 100;
          }
        });
        uploadData.url = res_upload.name;
        uploadData.isUploading = true;
        await this.saveUploadHandler(uploadData);
      } catch (error) {
        console.error(error);
        if (error.name === 'cancel') {
          this.$message.error('上传已取消');
          return;
        }
        this.$message.error('上传失败');
      }
    },
    async saveUploadHandler(uploadData) {
      const archive_id = this.formData.id;
      const sort = uploadData.sort;
      const resourceInfo = {
        url: uploadData.url,
        size: uploadData.size,
        name: uploadData.name,
        mime: uploadData.mime,
        suffix: uploadData.suffix,
        sign: uploadData.sign,
        duration: uploadData.duration
      };
      const { code, data } = await createAudioResource(
        archive_id,
        sort,
        resourceInfo
      );
      if (code !== 200) {
        this.$message.error('文件上传出错,请重试');
        uploadData.isComplete = false;
        return;
      }
      uploadData.id = data.res.id;
      uploadData.isUploading = false;
      uploadData.link_id = data.resLink.id;
      this.dispachEventUploading(false);
    },
    async dispachEventUploading(boolean) {
      if (boolean) {
        this.uploading.push(0);
      } else {
        this.uploading.shift();
      }
      this.isUploading = this.uploading.length !== 0;
    },

    async sortHandler(audios) {
      const sortData = [];
      for (const index in audios) {
        audios[index].sort = index;
        if (!audios[index].link_id) {
          continue;
        }
        sortData.push({
          id: audios[index].link_id,
          sort: index
        });
      }
      const { code, message } = await sortAudioResource(sortData);
      if (code !== 200) {
        this.$message.error('排序出错,请重试');
        return;
      }
      this.$message(message);
    },
    async deleteHandler(index, audio) {
      console.log(index, audio);
      if (audio.isUploading === true) {
        // 取消上传任务
        audio.ossClinet.cancel();
        this.resourcesList.splice(index, 1);
        return;
      }
      const { code, message } = await deleteAudioResource({ id: audio.id });
      if (code === 200) {
        this.resourcesList.splice(index, 1);
        this.$message(message);
      } else {
        this.$message.error(message);
      }
    },

    async getArchive(id) {
      const res = await getArchive({ id });
      this.formData = res.data;
    },
    async getParams() {
      const id = this.$route.params.id;
      return id;
    },
    async submit() {
      this.isSubmit = true;
      if (this.resourcesList.length < 1) {
        this.$message.error('至少上传一个资源 (｀・ω・´) ');
        return;
      }
      if (this.isUploading) {
        this.$message.error('有资源正在上传中 (｀・ω・´) ');
        return;
      }
      this.formData.state = 1;
      await setArchive(this.formData);
      this.$router.replace({ name: 'audiosList' });
    }
  }
};
